/**Filename: process.c
 * Author(s): Vladimir Dudnic, Michael Groenier, Derek Fleener
 * Winter 2013 TCSS422
 * Project 2
 */

#include"process.h"
#include<stdlib.h>
#include<time.h>

int COUNT = 30;
int kbints = 4;
int jbints = 2;
int memoryAccess = 10;
int processInit(Process* the_process, ProcessType the_type ,Instruction* instruction, int instructionSize, PROCESS_PRIORITY the_priority){
  int rv = 0;

  the_process->PC = 0;
  the_process->instructionSize = instructionSize;
  the_process->s = RUNNABLE;
  the_process->t = the_type;
  the_process->instructions = instruction;
  the_process->priority = the_priority;
  return rv;
}

Instruction processNextInstruction(Process* the_process){
  Instruction i;
  i = the_process->instructions[the_process->PC];

  the_process->PC = (the_process->PC + 1) % the_process->instructionSize;

  return i;
}

Process* createUI(){
  Process* newProcess;
  Instruction* instructions;
  Instruction temp;
  int i = 0;
  int randInstruction = 0;

  srand(time(NULL));

  instructions = (Instruction*)malloc(sizeof(Instruction) * COUNT);
  for(i = 0; i < COUNT; i++){
    temp.type = DUMB_INST;
    temp.arg = 0;
    instructions[i] = temp;
  }

  for(i = 0; i < kbints; i++){
    temp.type = IO_REQ;
    temp.arg = KEYBOARD;
    randInstruction = rand() % COUNT;
    instructions[randInstruction] = temp;
  }

  for(i = 0; i < jbints; i++){
    temp.type = IO_REQ;
    temp.arg = JOYSTICK;
    randInstruction = rand() % COUNT;
    instructions[randInstruction] = temp;
  }

  //randome requests for OS memory 0-3
  temp.type = MEM_UP;
  temp.arg = 0;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 1;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 2;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 3;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  newProcess =(Process*)malloc(sizeof(Process));
  processInit(newProcess, UI, instructions, COUNT, PRIORITY_VERY_HIGH);

  return newProcess;
}
Process* createCalc(){
  Process* newProcess;
  Instruction* instructions;
  Instruction temp;
  int i = 0;
  int randInstruction = 0;

  srand(time(NULL));

  instructions = (Instruction*)malloc(sizeof(Instruction) * COUNT);
  for(i=0;i<COUNT;i++){
    temp.type = DUMB_INST;
    temp.arg = 0;
    instructions[i] = temp;
  }

  for(i=0;i<kbints;i++){
    temp.type = IO_REQ;
    temp.arg = KEYBOARD;
    randInstruction = rand() % COUNT;
    instructions[randInstruction] = temp;
  }

  //randome requests for CALC memory 4-7
  temp.type = MEM_UP;
  temp.arg = 4;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 5;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 6;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  temp.type = MEM_UP;
  temp.arg = 7;
  randInstruction = rand() % COUNT;
  instructions[randInstruction] = temp;

  newProcess =(Process*)malloc(sizeof(Process));
  processInit(newProcess, CALC, instructions, COUNT, PRIORITY_LOW);
  return newProcess;
}
Process* createProd(int memAddress){
  Process* newProcess;
  Instruction* instructions;
  Instruction temp;
  int i = 0;
  int randInstruction = 0;

  srand(time(NULL));

  instructions = (Instruction*)malloc(sizeof(Instruction) *COUNT);
  for(i = 0; i < COUNT; i++){
    temp.type = DUMB_INST;
    temp.arg = 0;
    instructions[i] = temp;
  }

  for(i = 0; i < memoryAccess; i++){
    temp.type = MEM_UP;
    temp.arg = memAddress;
    randInstruction = rand() % COUNT;
    instructions[randInstruction] = temp;
  }

  newProcess =(Process*)malloc(sizeof(Process));
  processInit(newProcess, PROD, instructions, COUNT, PRIORITY_LOW);

  return newProcess;
}
Process* createCons(int memAddress){
  Process* newProcess;
  Instruction* instructions;
  Instruction temp;
  int i = 0;
  int randInstruction = 0;

  srand(time(NULL));

  instructions = (Instruction*)malloc(sizeof(Instruction) *COUNT);
  for(i = 0; i < COUNT; i++){
    temp.type = DUMB_INST;
    temp.arg = 0;
    instructions[i] = temp;
  }

  for(i = 0; i < memoryAccess; i++){
    temp.type = MEM_DN;
    temp.arg = memAddress;
    randInstruction = rand() % COUNT;
    instructions[randInstruction] = temp;
  }

  newProcess =(Process*)malloc(sizeof(Process));
  processInit(newProcess, CONS, instructions, COUNT, PRIORITY_AVG);

  return newProcess;
}

char* processStateToString(ProcessState the_state){
  char* message;

  switch(the_state){
  case RUNNING:
    message = malloc(8);
    message = "Running";
    break;
  case BLOCKED:
    message = malloc(8);
    message = "Blocked";
    break;
  case RUNNABLE:
    message = malloc(9);
    message = "Runnable";
    break;
  }
  return message;
}
char* processTypeToString(ProcessType the_type){
  char * message;

    switch(the_type){
    case UI:
      message = malloc(3);
      message = "UI";
      break;
    case CALC:
      message = malloc(5);
      message = "CALC";
      break;
    case PROD:
      message = malloc(5);
      message = "PROD";
      break;
    case CONS:
      message = malloc(5);
      message = "Cons";
      break;
    }
    return message;
}

